package com.franklin.ideaplugin.maphelper.utils;

import cn.hutool.core.collection.CollectionUtil;
import com.franklin.ideaplugin.api.beans.variable.IVariable;
import com.franklin.ideaplugin.api.utils.psi.PsiClassUtils;
import com.franklin.ideaplugin.maphelper.beans.colmember.IColMember;
import com.franklin.ideaplugin.maphelper.col.declaration.IColDeclaration;
import com.franklin.ideaplugin.maphelper.col.operation.ColOperationFactory;
import com.franklin.ideaplugin.maphelper.resolver.impl.map.MapMemberResolverFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;

import java.util.*;

/**
 * @author Ye Junhui
 * @since 2024/3/6
 */
public class PsiMapUtils {

    /**
     * 从代码块中寻找map成员
     *
     * @param mapVariable
     * @param psiCodeBlock
     * @return
     */
    public static List<IColMember> findMapMemberInCodeBlock(IVariable mapVariable, @Nullable PsiCodeBlock psiCodeBlock){
        return PsiColUtils.findColMemberInCodeBlock(
                mapVariable,
                psiCodeBlock,
                ColOperationFactory.MAP_READ_WRITE_OPERATIONS,
                MapMemberResolverFactory.getInstance()
        );
    }

    /**
     * 寻找集合定义
     * @param psiExpression
     * @return
     */
    @Nullable
    public static IColDeclaration findMapExpressionDeclaration(PsiElement psiExpression){
        return PsiColUtils.findColExpressionDeclaration(psiExpression);
    }

    /**
     * 寻找map表达式
     * @param psiElement
     * @return
     */
    public static PsiExpression getMapExpression(PsiElement psiElement){
        //当前PSI元素
        PsiReferenceExpression psiReferenceExpression = PsiTreeUtil.getParentOfType(psiElement, PsiReferenceExpression.class);
        if (Objects.isNull(psiReferenceExpression)){
            return null;
        }
        //表达式
        PsiExpression psiExpression = psiReferenceExpression.getQualifierExpression();
        if (Objects.isNull(psiExpression)){
            return null;
        }
        //变量类型
        PsiType psiType = psiExpression.getType();
        if (Objects.isNull(psiType)){
            return null;
        }
        //判断变量类型
        if (!PsiClassType.class.isInstance(psiType)){
            return null;
        }
        PsiClassType psiClassType = (PsiClassType) psiType;
        PsiClass psiClass = psiClassType.resolve();
        //是否是map类型
        if (!PsiClassUtils.isJavaMapClass(psiElement.getProject(), psiClass)){
            return null;
        }
        return psiExpression;
    }

    /**
     * 解析map成员
     * @param mapExpression
     * @return
     */
    public static Collection<IColMember> resolveMapMembers(PsiExpression mapExpression){
        //寻找map定义
        IColDeclaration<?> mapDeclaration = PsiMapUtils.findMapExpressionDeclaration(mapExpression);
        if (Objects.isNull(mapDeclaration)){
            return Lists.newArrayList();
        }
        return MapMemberResolverFactory.getInstance()
                .resolveExpression(mapExpression, mapDeclaration);
    }
}
